[따배도] - 컨테이너 네트워크


도커 네트워크 구성과 개념 그리고 명령어에 대해 알아봅시다.

컨테이너 통신 방법

docker0

  • docker0는 간단히 말해 하나의 네트워크 인터페이스
  • virtual ethernet bridge: 외부 네트워크와 도커 컨테이너의 연결 다리 역할을 하는 네트워크의 한 종류

    • 기본 네트워크 대역: 172.17.0.0/16 / docker0는 172.17.0.1를 통해서 게이트웨이 역할을 해줌
    • NAT(Network Address Translate), 포트포워딩 지원 - iptables를 통해서 지원해 줌
    • L2 통신기반
    • Container 생성 시 veth 인터페이스 생성(sandbox)

도커 네트워크 구성도

1  도커 네트워크구성
  • ip addr 명령어를 통해 네트워크 카드 확인

    • eth0 - 호스트 이더넷, docker0 네트워크 확인 가능

2  아이피 확인

컨테이너 포트를 외부에 노출하는 방법

  • container port를 외부로 노출시켜 외부 연결을 허용해줄 수 있습니다.
  • iptalbes rule을 통한 포트 노출 - 포트포워딩

    • -p hostPort:containerPort : 가장 기본적인 방식
    • -p containerPort : 이 경우 호스트 포트는 random
    • -P : EXPOSE로 맞춰진 수만큼 컨테이너의 포트를 열고, 호스트 포트는 random 한 값을 도커에서 자동 설정
  • 포트포워딩 예시 및 iptables 명령어를 통해 확인
$ docker run --name web -d -p 80:80 nginx:latest
$ iptables -t nat -L -nv

3  iptables 명령어를 통해 확인

컨테이너 네트워크 추가하는 방법

사용자정의 bridge network 생성

  • 네트워크 대역을 사용자 정의 네트워크로 만들어서 연결이 가능합니다.

    • docker network create 명령어를 사용해서 만들 수 있습니다.
    • 물론 docker0의 네트워크 대역도 변경 가능합니다.
# --driver : default값은 bridge / bridge로 설정하고 싶다면 생략 가능
# --subnet : 사용자가 네트워크 대역을 정의
# --gateway : gateway를 정의하지 않았다면 default 값은 192.168.100.1이 되었을 것임(docker0의 네트워크처럼)
# mynet : 네트워크 이름
$ docker network create --driver bridge --subnet 192.168.100.0/24 --gateway 192.168.100.254 mynet
  • 만들어진 네트워크를 사용하는 방법

    • 사용자 정의 네트워크 사용 시, 위에서 언급한대로 ip대역 설정이 가능합니다.
# --net : 사용할 네트워크 지정
# --ip : 고정 ip주소 사용
$ docker run -d -it --name c1 --net mynet --ip 192.168.100.100 -p 8080:8080 busybox
$ ip addr # 해당 명령어를 통해 ip가 192.168.100.100이라는 것을 확인할 수 있음

조금 더 자세히 알아보기

  • 컨테이너 실행하기
$ docker run -p 80:80 --name c1 -it busybox
$ docker inspect c1
  • 자세히 알아보기

    • 위의 네트워크 구성도 참고

1  network inspect

  • iptables 명령어를 통해 네트워크 인터페이스 확인
$ iptables -t nat -L -v

2  아이피테이블스

💡

MASQUERADE란

사설망의 IP를 외부IP와 통신이 가능하게 해주는 것을 의미한다. 즉, NAT의 역할을 해줌!

컨테이너끼리 통신하는 방법

컨테이너간 통신이 필요할 때가 있는데 예를 들어서 프론트 단과 백엔드 단이 구성되어 있는 멀티 티어 같은 구조입니다. 프론트에서 만들어진 데이터를 백엔드에 저장하고 또는 데이터를 가져와야 할 때 사용하게 됩니다. 이때 각각의 컨테이너가 독립적으로 운용된다고 하였을 때 컨테이너 간의 통신이 필요하므로 컨테이너 간의 통신이 필요하게 됩니다.

💡

알고가기!

기본적으로 컨테이너는 서로 독립적인 격리 상태 구조입니다.

예시를 통해 알아봅시다.

  • 워드프레스는 기본적으로 아파치 웹서버를 내장하고 있고 워드프레스를 이용하여 웹을 제작하려고 할 때, 데이터베이스가(백엔드 단)이 필요하게 됩니다.
  • 데이터베이스 생성

    • MYSQL_ROOT_PASSWORD: mysql의 root 사용자 비밀번호
    • MYSQL_PASSWORD : 워드프레스가 사용하는 패스워드
$ docker run -d --name mysql -v /dbdata:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=wordpress -e MYSQL_PASSWORD=wordpress mysql:5.7
  • /dbdata - volume 확인

3  mysql volume

  • 워드프레스 생성

    • --link : 명령어를 통해 mysql 컨테이너와 연결
    • mysql:mysql : <연결할 컨테이너 명>:<이름 사용자 지정>
    • -e WORDPRESS_DB_PASSWORD : 워드프레스 db에 사용하는 패스워드(mysql 컨테이너에서 설정한 것)
# $ docker run -d --name wordpress --link mysql:mysql -e WORDPRESS_DB_USER=root -e WORDPRESS_DB_PASSWORD=wordpress -p 80:80 wordpress:latest

# 수정
$ docker run -d --name wordpress --link mysql:mysql -p 8080:80 wordpress:latest

해당 설정을 통해 호스트 /dbdata path에 데이터가 쌓이게 되고 프론트, 백엔드 단 설정이 완료됩니다.

WORDPRESS_DB_PASSWORD 환경변수 부분 문제로 오랜시간이 걸렸다.. mysql 대신 다른 db 사용 시 걸어주는 옵션(도커허브 공식 이미지 참조함)

4  wordpress

연습문제

  1. genid 컨테이너 생성

    • 해당 컨테이너는 shell-script를 통해 index.html의 데이터를 만들어 낸다.
    • 해당 index.html 데이터를 볼륨을 통해 호스트 PC와 공유한다.
  2. nginx

    • genid 컨테이너 볼륨에서 만들어진 데이터와 nginx를 통해 웹 서비스를 진행한다.
  3. genid 컨테이너에 사용할 [genid.sh] 스크립트 생성
$ cat genid.sh

#!/bin/bash
mkdir -p /webdata
while true
do
  /usr/bin/rig | /usr/bin/boxes -d boy > /webdata/index.html
  sleep 5
done
  • genid 컨테이너에 사용할 [Dockerfile] 생성
$ cat Dockerfile

FROM ubuntu:18.04
RUN apt-get update; apt-get -y install rig boxes
ADD genid.sh /bin/genid.sh
RUN chmod +x /bin/genid.sh
ENTRYPOINT ["/bin/genid.sh"]

nginx는 genid가 만들어 내는 데이터를 사용해야 하기 때문에 데이터를 쌓기 위해선 genid 먼저 실행 시켜야 합니다.

  • genid 컨테이너 실행
$ docker run -d -v ./webdata:/webdata --name genid genid
  • 컨테이너 실행 후, 볼륨 경로에 데이터가 쌓이는지 확인

5  volume데이터

  • nginx 실행

    • genid가 만들어내는 데이터 index.html를 nginx가 사용하므로, volume 경로를 설정
$ docker run -d -v /webdata:/usr/share/nginx/html -p 8080:80 --name nignx nginx
  • 웹 사이트에서 검증

나오긴하는데 UI가 맞춰서 나오지는 않았습니다…

6  최종확인

  • curl 명령어를 통해 재검증

    • nginx의 포트포워딩 주소인 localhost:8080 입력 시 잘 나오는 것을 확인

6-1  최종확인

Reference

도커 네트워크 구성
iptables 명령어
도커 공식 레퍼런스


Hello, I'm@nickhealthy
개발자를 꿈꾸고, 파이썬과 클라우드에 관심이 많은 비전공자

Github